package com.example.private_auto_install.ftpGIt;

import org.apache.log4j.Logger;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;


/**
 * @Description: 理化生的自动发布 流程走起
 * @Author: by
 * @Date: 2022-03-02
 **/
public class MainIndex {


    public static Logger publishLogProcess = Logger.getLogger("publishLogProcess");
    /**
     * 项目的根目录  后续所有的更目录都按当前的类的进行使用
     */
    public static String projectPath = "E:\\化学仿真实验\\organicchemistry";

    /**
     * 是否测试环境
     */
    public static boolean isTestflag = false;


    /**
     * 是否全部发布
     */
    public static boolean publishIsAll = true;

    /**
     * 监听的对象，
     */
    public static FileListener fileListener = new FileListener();

    /**
     * git 地址
     */
    public static String gitPathHttp = "http://192.168.20.122:82/zl-simulation-exper/organicchemistry.git";

    /**
     * 初始化项目路径
     */
    public static void initConfig() {
        if (isTestflag) {
//            如果是测试，则使用字符串路径
            projectPath = "E:\\化学仿真实验\\organicchemistry";
        } else {
            //如果不是测试，则使用相对路径 因为jar包放置到项目下一级目录中
            projectPath = UtilFile.getProjectPath();
            // 然后获取它的上级目录
            projectPath = projectPath.substring(0, projectPath.lastIndexOf(File.separator));
        }
    }

    /**
     * 记录，打包的时候 需要删除 ECLIPSE_.SF文件
     *
     * @param args
     */
    public static void main(String[] args) {
        initConfig();
//        立即执行增量发布
        publishLogProcess.info("************************************************************************************************");
        //执行任务
        publishLogProcess.info(new Date() + "化学有机自动发布启动");

//        setTime();
//        增量更新
        incrementalUpdating();
//        直接全部发布
//        allPublishEgret();
    }

    public static void setTime() {
        //早上8.30
        timing(8, 1);
        //早上8.30
//        timing(9, 1);//早上8.30

        timing(10, 1);
//        timing(11, 1);
        //中午12：15
        timing(12, 1);
        //中午12：15
        timing(14, 1);
        //中午12：15
//        timing(15, 1);
        //下午16:00
        timing(16, 1);
        //晚上
//        timing(17, 1);
        //晚上
        timing(18, 1);
        //晚上
        timing(19, 1);
        //晚上
//        timing(20, 1);
        //晚上
        timing(21, 1);
    }

    /**
     * 增量更新
     */
    public static boolean incrementalUpdating() {
        publishLogProcess.info("开始增量更新" + "\\n");
        //当前自动发布是依据PCB
//        1.执行git命令，拉取当前代码
        JGitHandle.initConfig(projectPath, gitPathHttp);
        boolean flag = JGitHandle.gitPull();
        boolean publishSuccess = true;
//        2.如果拉取到代码 则进行发布
//        if (flag) {
            //拉取到代码，则进行更新json文件
            fileListener.restartCreateJSON_PCB(projectPath);
//           3.将拉取到的增量更新代码发布到服务器的指定位置
            //因项目路径问题，所以这里得新增一个项目路径去除
            Ftp.uploadingFiles();
//           4.然后执行发布命令，将egret 发布
            boolean publishFlag = BatHandle.publishEgret(projectPath);
//           5.然后将发布出来的文件，进行整理，再次上传到
            if (publishFlag) { //如果发布成功，
                //5.1进行增量更新，
                publishSuccess = Ftp.uploadPublishFiles();
            }
            if (publishIsAll) {
//           6.默认基础路径发布 ---做增量发布的时候不执行当前包
                publishLogProcess.info("全部发送基础路径");
                publishSuccess = Ftp.uploadBaseFile_PCB(projectPath);
            }
            //如果发布成功，则进行发送
            if (publishSuccess) {
                publishLogProcess.info("发送邮件");
                sendMailtoAll();
            }
//        }
        return true;
    }

    /**，
     * 直接全部发布
     */
    public static boolean allPublishEgret() {
//        1.执行git命令，拉取当前代码
        JGitHandle.initConfig(projectPath, gitPathHttp);
        boolean flag = JGitHandle.gitPull();
        fileListener.restartCreateJSON_PCB(projectPath);
        boolean publishSuccess = true;
//        2.如果拉取到代码 则进行发布

//       3.将拉取到的增量更新代码发布到服务器的指定位置
        //因项目路径问题，所以这里得新增一个项目路径去除
        Ftp.uploadingFiles();
//           4.然后执行发布命令，将egret 发布
        boolean publishFlag = BatHandle.publishEgret(projectPath);
//           5.然后将发布出来的文件，进行整理，再次上传到
        if (publishFlag) { //如果发布成功，
            //5.1进行增量更新，
            publishSuccess = Ftp.uploadPublishFiles();
        }
        if (publishIsAll) {
            publishLogProcess.info("所有基础包开始发送");
//           6.默认基础路径发布 ---做增量发布的时候不执行当前包
            publishSuccess = Ftp.uploadBaseFile_PCB(projectPath);
        }
        //如果发布成功，则进行发送
        if (publishSuccess) {
            publishLogProcess.info("发送邮件");
            sendMailtoAll();
        }

        return true;
    }

    /**
     * 每天几点执行定时任务   24小时制时间 例: 08:00:00  20:00:00
     *
     * @param hour   小时
     * @param minute 分
     */
    private static void timing(final int hour, final int minute) {
        Timer timer = new Timer();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, hour);//控制小时
        calendar.set(Calendar.MINUTE, minute);//控制分钟
        calendar.set(Calendar.SECOND, 0);//控制秒
        Date time = calendar.getTime();//执行任务时间为12:00:00

        TimerTask task = new TimerTask() {
            public void run() {
                publishLogProcess.info(hour + ":" + minute + " 点定时器执行");
                //这里增加一层判断。 获取当前小时，
                Calendar calNow = Calendar.getInstance();
                int hourNow = calNow.get(Calendar.HOUR_OF_DAY);
                // 只有当前小时和发布小时一样，才会进行发布，防止启动的时候，时间点过去了，启动发布
                if (hourNow == hour) {
                    publishLogProcess.info("************************************************************************************************");
                    //执行任务
                    publishLogProcess.info(hour + ":" + minute + "发布开始");
                    //增量更新
                    incrementalUpdating();
                }

            }
        };
        //每天定时12:00执行操作，延迟一天后再执行
        timer.schedule(task, time, 1000 * 60 * 60 * 24);

    }

    /**
     * 调用对方接口方法
     *
     * @param path 对方或第三方提供的路径
     * @param data 向对方或第三方发送的数据，大多数情况下给对方发送JSON数据让对方解析
     */
    public static void interfaceUtil(String path, String data) {
        InputStream inputStream = null;
        try {
            System.out.println("interfaceUtil");
            URL url = new URL(path);
            //打开和url之间的连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            PrintWriter out = null;
            //请求方式
            conn.setRequestMethod("POST");
//           //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            //设置是否向httpUrlConnection输出，设置是否从httpUrlConnection读入，此外发送post请求必须设置这两个
            //最常用的Http请求无非是get和post，get请求可以获取静态页面，也可以把参数放在URL字串后面，传递给servlet，
            //post与get的 不同之处在于post的参数不是放在URL字串里面，而是放在http请求的正文内。
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            //发送请求参数即数据
            out.print(data);
            //缓冲数据
            out.flush();
            //获取URLConnection对象对应的输入流

            inputStream = conn.getInputStream();
            //构造一个字符流缓存
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            String str = "";
            while ((str = br.readLine()) != null) {
                System.out.println(str);
            }
            //关闭流
            inputStream.close();
            //断开连接，最好写上，disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
            //固定多线程的话，如果不disconnect，链接会增多，直到收发不出信息。写上disconnect后正常一些。
            conn.disconnect();
            publishLogProcess.info("完整结束");
        } catch (Exception e) {
            publishLogProcess.info("发送邮件失败");
            publishLogProcess.error(e);
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 发布完成后，给所有人发送邮件提醒。
     */
    public static void sendMailtoAll() {
        Map<String, String> map = new HashMap<>();
        map.put("白宇", "gta6473@dingtalk.com");

//        map.put("梁祥君", "liangxiangjun7076@dingtalk.com");
//        map.put("张建新", "zhangjianxin6761@dingtalk.com");
//        map.put("赵云钰", "zhaoyunyu6087@dingtalk.com");
//        map.put("尉瑶", "iiv9557@dingtalk.com");

        Iterator it = map.entrySet().iterator();
        String names = "";
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            Object key = entry.getKey();
            String value = entry.getValue().toString();
            names += key.toString() + "，";
            try {
                MailUtil.sendMsg(value, "化学有机发布成功", key + "请访问： http://192.168.122.135:89/  查看项目");

            } catch (Exception e) {
                e.printStackTrace();
            }
//            String Path = "http://192.168.1.205:6001/site/web/member/sendEmailOK?emailAddress=" + value+"&eamailMsg='理化生发布成功：192.168.122.135:94'" ;
//            interfaceUtil(Path, "");
        }
        publishLogProcess.info("发送邮件结束" + "发送人【" + names + "】");

    }
}
